package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql" //需用到init()方法
)

var Db *sql.DB // 全局db
func initDB() error {
	var err error
	//如果使用全局db，那么open返回变量不使用冒号
	//Db, err = sql.Open("mysql", "root:mysql@tcp(127.0.0.1:3306)/gotest")

	//go-sql-driver默认时间为UTC时间，因此在驱动注册连接数据库时需指定时区
	Db, err = sql.Open("mysql", "root:mysql@tcp(127.0.0.1:3306)/gotest?charset=utf8&loc=Asia%2FShanghai")
	if err != nil {
		fmt.Println("mysql连接错误", err)
		return err
	}
	Db.SetMaxOpenConns(10) //设置最大连接数
	Db.SetMaxIdleConns(5)  //最大空闲数
	return nil
}

func initDb() (db *sql.DB, err error) {
	//如果使用全局db，那么open返回变量不使用冒号
	//db, err := sql.Open("mysql", "root:mysql@tcp(127.0.0.1:3306)/gotest")

	//go-sql-driver默认时间为UTC时间，因此在驱动注册连接数据库时需指定时区
	db, err = sql.Open("mysql", "root:mysql@tcp(127.0.0.1:3306)/gotest?charset=utf8&loc=Asia%2FShanghai")
	if err != nil {
		fmt.Println("mysql连接错误", err)
		return
	}
	return
}

func main() {
	//db,err := initDb()
	//if err != nil {
	//	fmt.Println("mysql连接错误", err)
	//	return
	//}
	//defer db.Close()

	err := initDB()
	if err != nil {
		fmt.Println("mysql连接错误", err)
		return
	}

	//查询
	//返回多个值
	rows, err := Db.Query("select id, name from user")
	if err != nil {
		fmt.Println("查询错误", err)
	}
	//一定要关闭rows查询集，否则在使用完后不会释放连接
	defer func() {
		if err != nil {
			rows.Close()
		}
	}()
	for rows.Next() {
		var id int
		var name string
		//必须使用Scan，否则连接一直挂起不能释放
		rows.Scan(&id, &name)
		fmt.Println("用户id：", id, "用户名：", name)
	}
	fmt.Println("--------------------")
	//返回最多一个值
	//sqlStr := "select id, name from users where id=?"
	//row := Db.QueryRow("select id, name from users where id=?", 1)

	//预处理
	stmt, err := Db.Prepare("select id, name from user where id=?")
	if err != nil {
		fmt.Println("预处理错误", err)
	}
	row, _ := stmt.Query(3)
	var id int
	var name string
	//预处理方式，必须row.Next()，否则取不到值
	row.Next()
	row.Scan(&id, &name)
	fmt.Printf("用户id：%d, 用户名：%s\n", id, name)

	//增
	//insert,err:=Db.Exec("insert into users(name) values ('小强')")
	//if err!=nil{
	//	fmt.Println("插入数据错误", err)
	//}
	//idInsert, err:=insert.LastInsertId()
	//if err!=nil{
	//	fmt.Println("最后一条id错误", err)
	//}
	//fmt.Println("插入id是：", idInsert)

	//更新
	update, err := Db.Exec("update user set name='小美' where id>=?", 6)
	if err != nil {
		fmt.Println("更新错误", err)
	}
	rowsAff, _ := update.RowsAffected()
	fmt.Println("影响行数：", rowsAff)

	// 删
	del, err := Db.Exec("delete from user where id =?", 5)
	if err != nil {
		fmt.Println("删除错误", err)
	}
	rowsAff, _ = del.RowsAffected()
	fmt.Println("影响行数：", rowsAff)

	//事务
	//开启
	//tx, err:=Db.Begin()
	/*
		代码块
	*/
	//提交
	//tx.Commit()
	//回滚
	//tx.Rollback()

}
